package org.finegold.core.pay.wx.api;

import lombok.extern.slf4j.Slf4j;
import org.finegold.core.pay.common.bean.CertStoreType;
import org.finegold.core.pay.common.util.sign.SignUtils;
import org.finegold.core.tool.utils.Func;
import org.finegold.core.pay.api.PayApi;
import org.finegold.core.pay.common.api.PayService;
import org.finegold.core.pay.common.bean.PayOrder;
import org.finegold.core.pay.common.http.HttpConfigStorage;
import org.finegold.core.pay.wx.config.WxPayConfig;
import org.finegold.core.pay.wx.model.OderModelDTO;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class WxPayApi implements PayApi {

	private static ConcurrentHashMap<String,WxPayService> wxPayServiceMap;
	public final WxPayConfig wxPayConfig;
	public WxPayApi(WxPayConfig wxPayConfig) {
		this.wxPayConfig=wxPayConfig;
	}

	@Override
	public WxPayService getWxPayService(Map<String, Object> map) {
		WxPayService wxPayService=null;
		WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
		wxPayConfigStorage.setMchId(String.valueOf(map.get("mchId")));
		wxPayConfigStorage.setAppid(String.valueOf(map.get("appId")));
		wxPayConfigStorage.setKeyPublic(wxPayConfig.getKeyPublic());
		wxPayConfigStorage.setSecretKey(String.valueOf(map.get("privateKey")));
		wxPayConfigStorage.setNotifyUrl(wxPayConfig.getNotifyUrl()+String.valueOf(map.get("notifyUrl")));
		wxPayConfigStorage.setSignType(SignUtils.MD5.name());
		wxPayConfigStorage.setInputCharset("utf-8");
		wxPayService = new WxPayService(wxPayConfigStorage);
		HttpConfigStorage httpConfigStoragez = new HttpConfigStorage();
		//ssl 退款证书相关 不使用可注释
		if (Func.isNotEmpty(map.get("mchId"))) {
			//ssl 退款证书相关
			httpConfigStoragez.setKeystore(String.valueOf(map.get("sslRefundUrl")));
			httpConfigStoragez.setStorePassword(String.valueOf(map.get("mchId")));
			//设置ssl证书对应的存储方式，这里默认为文件地址
			httpConfigStoragez.setCertStoreType(CertStoreType.PATH);
		}
		httpConfigStoragez.setMaxTotal(20);
		//默认的每个路由的最大连接数
		httpConfigStoragez.setDefaultMaxPerRoute(10);
		wxPayService.setRequestTemplateConfigStorage(httpConfigStoragez);
		if(Func.isEmpty(WxPayApi.wxPayServiceMap)){
			WxPayApi.wxPayServiceMap = new ConcurrentHashMap();
		}
		WxPayApi.wxPayServiceMap.put(String.valueOf(map.get("appId"))+"-"+String.valueOf(map.get("notifyUrl")),wxPayService);
		WxPayApi.wxPayServiceMap.put(String.valueOf(map.get("appId")),wxPayService);
		return wxPayService;
	}

	@Override
	public WxPayService getWxPayService(String appId){
		WxPayService wxPayService = wxPayServiceMap.get(appId);
		return wxPayService;
	}

	@Override
	public WxPayService createSign(String notifyUrl){
		WxPayService wxPayService=null;
		if(Func.isNotEmpty(WxPayApi.wxPayServiceMap)){
			wxPayService = WxPayApi.wxPayServiceMap.get(wxPayConfig.getAppId()+"-"+notifyUrl);
		}
		if(Func.isEmpty(wxPayService)) {
			WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
			wxPayConfigStorage.setMchId(wxPayConfig.getMchId());
			wxPayConfigStorage.setAppid(wxPayConfig.getAppId());
			wxPayConfigStorage.setKeyPublic(wxPayConfig.getKeyPublic());
			wxPayConfigStorage.setSecretKey(wxPayConfig.getPrivateKey());
			wxPayConfigStorage.setNotifyUrl(wxPayConfig.getNotifyUrl()+notifyUrl);
			wxPayConfigStorage.setSignType(SignUtils.MD5.name());
			wxPayConfigStorage.setInputCharset("utf-8");
			wxPayService = new WxPayService(wxPayConfigStorage);
			HttpConfigStorage httpConfigStoragez = new HttpConfigStorage();
			//ssl 退款证书相关 不使用可注释
			if (Func.isNotEmpty(wxPayConfig.getSslRefundUrl())) {
				//ssl 退款证书相关
				httpConfigStoragez.setKeystore(wxPayConfig.getSslRefundUrl());
				httpConfigStoragez.setStorePassword(wxPayConfig.getMchId());
				//设置ssl证书对应的存储方式，这里默认为文件地址
				httpConfigStoragez.setCertStoreType(CertStoreType.PATH);
			}
			httpConfigStoragez.setMaxTotal(20);
			//默认的每个路由的最大连接数
			httpConfigStoragez.setDefaultMaxPerRoute(10);
			wxPayService.setRequestTemplateConfigStorage(httpConfigStoragez);
			if(Func.isEmpty(WxPayApi.wxPayServiceMap)){
				WxPayApi.wxPayServiceMap = new ConcurrentHashMap();
			}
			WxPayApi.wxPayServiceMap.put(wxPayConfig.getAppId()+"-"+notifyUrl,wxPayService);
			WxPayApi.wxPayServiceMap.put(wxPayConfig.getAppId(),wxPayService);
		}
		return wxPayService;
	}


	/**
	 * <B>Description:</B> 获取返回参数
	 * @author QinXueFeng
	 * @date 2020/9/8 12:42
	 * @param wxPayService
	 * @param wxModel
	 * @return
	 */
	@Override
	public  Map<String, Object> send(PayService wxPayService, OderModelDTO wxModel) {
		PayOrder order = new PayOrder(wxModel.getSubject(), wxModel.getBody(), wxModel.getPrice(), wxModel.getOutTradeNo());
		order.setTransactionType(wxModel.getTransactionType());
		return wxPayService.orderInfo(order);
	}

	/**
	 * 关闭订单
	 * @param wxPayService
	 * @param tradeNo    支付平台订单号
	 * @param outTradeNo 商户单号
	 * @return
	 */
	@Override
	public Map close(PayService wxPayService,String tradeNo, String outTradeNo) {
		Map close = wxPayService.close(tradeNo, outTradeNo);
		return close;
	}
}
